package system.task.logger;

import lombok.Getter;
import lombok.SneakyThrows;
import org.springframework.util.StringUtils;
import system.task.TaskLogger;
import system.task.config.TaskConfig;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

public class TaskLoggerImpl implements TaskLogger, AutoCloseable {

    private final TaskConfig taskConfig;
    private DateTimeFormatter formatter;
    @Getter
    private final List<TaskLoggerWriter> logWriters;
    @Getter
    private final TaskLoggerStdWriter stdWriter;

    public TaskLoggerImpl(TaskLoggerContext taskLoggerContext) {
        this.taskConfig = taskLoggerContext.getConfig();
        this.runId = taskLoggerContext.getRunId();
        this.logWriters = taskLoggerContext.getLogWriters();
        this.setPrefixTime(this.taskConfig.getLogPrefixTime());
        //
        this.stdWriter = findStdWriter(taskLoggerContext.getLogWriters());
    }

    private static TaskLoggerStdWriter findStdWriter(List<TaskLoggerWriter> logWriters) {
        for (TaskLoggerWriter writer : logWriters) {
            if (writer instanceof TaskLoggerStdWriter) {
                return (TaskLoggerStdWriter) writer;
            }
        }
        return null;
    }

    @Override
    public void setPrefixTime(String format) {
        if (StringUtils.hasText(format))
            this.formatter = DateTimeFormatter.ofPattern(format);
        else
            this.formatter = null;
    }

    private final String runId;

    @Override
    public String getRunId() {
        return this.runId;
    }

    @Override
    public String getPath() {
        if (stdWriter != null) {
            return stdWriter.getPath();
        }
        return null;
    }

    @Override
    public boolean hasContent() {
        if (stdWriter != null) {
            return stdWriter.isHasContent();
        }
        return false;
    }

    @Override
    public boolean isEnabled() {
        return this.logWriters.size() > 0;
    }

    @SneakyThrows
    public void write(String s) {
        if (this.logWriters.size() > 0) {
            for (TaskLoggerWriter logWriter : this.logWriters) {
                logWriter.info(null, s, false);
            }
        }
    }

    @Override
    public void writeln(String var1) {
        if (this.logWriters.size() > 0) {
            String time = null;
            DateTimeFormatter formatter = this.formatter;
            if (formatter != null) {
                time = ZonedDateTime.now().format(formatter);
            }
            for (TaskLoggerWriter logWriter : this.logWriters) {
                logWriter.info(time, var1, true);
            }
        }
    }

    @Override
    public void error(String var1) {
        if (this.logWriters.size() > 0) {
            String time = null;
            DateTimeFormatter formatter = this.formatter;
            if (formatter != null) {
                time = ZonedDateTime.now().format(formatter);
            }
            for (TaskLoggerWriter logWriter : this.logWriters) {
                logWriter.error(time, var1, true);
            }
        }
    }

    @Override
    public synchronized void close() throws Exception {
        // close writers
        List<TaskLoggerWriter> writers = this.logWriters;
        for (TaskLoggerWriter loggerWriter : writers) {
            try {
                loggerWriter.close();
            } catch (Throwable throwable) {
                // ignore close error
            }
        }
        writers.clear();
    }

}
